package com.letoken.platform.admin.configuration;

import com.amazonaws.util.StringUtils;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

@Configuration
@EnableWebMvc
public class JacksonConfig implements WebMvcConfigurer {

    /**
     * 添加到消息转换器
     * @param converters
     */
    @Override
    public void configureMessageConverters(List <HttpMessageConverter<?>> converters) {
        //如果放在jacson下面会出现字符串多一个的问题
        converters.add(stringHttpMessageConverter());
        converters.add(jackson2HttpMessageConverter());
    }

    /**
     * 处理返回json格式
     * 定义时间格式转换器
     * @return MappingJackson2HttpMessageConverter
     */
    @Bean
    public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //主要是这句处理
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //时间格式化
//        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        JavaTimeModule timeModule = new JavaTimeModule();
        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());


        mapper.registerModule(timeModule);

        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(BigDecimal.class,new DataSerializerBigDecimal());
        mapper.registerModule(simpleModule);

        converter.setObjectMapper(mapper);

        List<MediaType> list = Arrays.asList(
                MediaType.APPLICATION_JSON,
                MediaType.ALL);//防止spring boot admin报错(No converter for [class org.springframework.boot.actuate.health.SystemHealth] with preset Content-Type 'null')
        converter.setSupportedMediaTypes(list);
        return converter;
    }

    static class DataSerializerBigDecimal extends JsonSerializer<BigDecimal>{
        // 流出序列化
        @Override
        public void serialize(BigDecimal value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
            if (ObjectUtils.isEmpty(value)) jsonGenerator.writeNumber(0.0);
            else jsonGenerator.writeNumber(new BigDecimal(value.setScale(8, RoundingMode.DOWN).stripTrailingZeros().toPlainString()));
        }
    }


    @Bean
    public StringHttpMessageConverter stringHttpMessageConverter() {
        return new StringHttpMessageConverter();
    }



    static class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        private static DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");



        @Override
        public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (ObjectUtils.isEmpty(localDateTime)) jsonGenerator.writeString("");
            else jsonGenerator.writeString(localDateTime.format(fmt));
        }
    }

    static class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {

        private static DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        @Override
        public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            String timestamp = jsonParser.getValueAsString();
            if (StringUtils.isNullOrEmpty(timestamp))
                return null;
            return LocalDateTime.parse(timestamp, fmt);
        }
    }

}




